#include "pcapwrapper.h"
#include <QDebug>

void callback(u_char *data, const struct pcap_pkthdr *,const u_char * packet)
{
    struct iphdr * ipprt;
    ipprt = (struct iphdr *)(packet + sizeof(struct ether_header));

    if (ipprt->protocol != IPPROTO_TCP) // != TCP
        return;

    struct tcphdr * tcpptr;
    tcpptr = (struct tcphdr *)(packet + sizeof(struct ether_header) + sizeof(struct iphdr));

    std::queue<PacketHeader> * packets = reinterpret_cast<std::queue<PacketHeader> *>(data);

    PacketHeader pkt;
    pkt.setTcpHeader(*tcpptr);
    pkt.setIpHeader(*ipprt);

    packets->push(pkt);
}

PcapWrapper::PcapWrapper() : started(false)
{
    //
}

PcapWrapper::~PcapWrapper()
{
    stopCapture();
}

bool PcapWrapper::isStarted()
{
    return started;
}

void PcapWrapper::setInterfaceName(QString deviceName)
{
    this->interfaceName = deviceName;
}

QString PcapWrapper::getInterfaceName()
{
    return interfaceName;
}

QList<Interface> PcapWrapper::getInterfaces()
{
    QList<Interface> list;

    pcap_if_t * interfaces;
    pcap_findalldevs(&interfaces,err);

    while(interfaces->next){

        pcap_t * tmp = pcap_open_live(interfaces->name,BUFSIZ,false,-1,err);
        int datalink_type = pcap_datalink(tmp);
        pcap_close(tmp);

        Interface device;
        device.name = interfaces->name;
        device.datalink_type = datalink_type;

        list.append(device);

        interfaces = interfaces->next;
    }

    return list;
}

std::queue<PacketHeader> & PcapWrapper::getCapturedPackets()
{
    return captured_packets;
}

void PcapWrapper::startCapture()
{
    started = true;
    start();
}

void PcapWrapper::stopCapture()
{
    if(not started)
        return;

    if(handler == NULL)
        return;

    pcap_breakloop(handler);
    pcap_close(handler);

    if(isRunning())
        terminate();

    started = false;
}

void PcapWrapper::run()
{
    handler = pcap_open_live(interfaceName.toAscii(),BUFSIZ,false,LOOP_FOREVER,err);
    pcap_loop(handler,LOOP_FOREVER,callback,(u_char*)(&captured_packets));
}
